let typeSet = new Set([Date,RegExp,DataView,Promise])
function deepClone(obj){
    let   copy ;
    if( !obj ||  typeof obj !=='object'){ return obj}
    // 确实数组要单独处理
    if(Array.isArray(obj)){ copy = []  }
    else if( obj.constructor === Date){ return new Date(obj)     }
    else if( obj.constructor === RegExp){ return new RegExp(obj)  }
    else   copy = {}
    for( let key of  Reflect.ownKeys(obj)){
        if(typeof  obj[key] === 'object' && typeof obj[key] !=='undefined' ){
            copy[key] = deepClone(obj[key])
        }else {
            copy[key] = obj[key]
            
        }
    }
    return  copy
}
/* 可以尝试改成层序 ，就不用这种递归了 好像有点问题 ，
应该是这样的思路， 规则的就用json  规则就是指js内置的对象，另外的键值对对象才用递归。  日期对象parse还原不了，map也是。
看来使用json 的场景就是纯数据
 现在的漏洞应该就是typeArray arrayBuffer dataview 还有set  map, 常规的还有Date reg 正则也是特殊的对象*/

const obj1 ={}
Object.defineProperties(obj1, {
    a:{
        configurable:true ,
        writable:true,
        enumerable:false,// 可枚举
        value: 'a'
    },
    b:{
        value: 'b'
    }
})

console.log( obj1.a)

/* 原来。。我理解的观察者模式是发布订阅，观察者模式更简单直接 发布订阅就是多个观察者 */
class Obeservar{
    constructor(){
        this.eventsmap = new  Map()
    }
    addEvent(EventName, fn){
        let queue = this.eventsmap.get(EventName) || new Set()
        queue.add(fn)
        this.eventsmap.set(EventName. queue)
    }

    remove(EventName, fn){
        if(!this.eventsmap.has(EventName)){ return}
        this.eventsmap.get(EventName).delete(fn) ;
    }

    emit(eventName, ...args){
        let queue = this.eventsmap.get(eventName) ;
        if(queue){
            queue.foreach((fn)=>{
                fn(...args)
            })
        }
    }
}

class Subject{
    constructor(){
        this.deps = new Set()
    }
    add(fn){
        this.deps.add(fn)
    }
    trigger(...values){
        for( let dep of this.deps){
            dep(...values)
        }
    }
    del(fn){
        this.deps.delete(fn)
    }

}
// 实现new 方法？  new 方法的参数应该是一个函数。  

 function  myNew(constructorFn =()=>{},...args){ 
    // 1先创建一个空对象 
    let instance = new Object() ;
    // 2让函数内部的this 指向它
    instance.constructor = constructorFn ;
    // 实例的原型对象指向 函数的原型
    // instance.__prototype__ = constructorFn.prototype ;
    Object.setPrototypeOf(instance,constructorFn.prototype);
    // 执行函数 ；如果返回一个非空对象，就返回这个对象，否则返回
    let result =  instance.constructor(...args) ;
    return  result && typeof result ==='object' ?result:instance
 }


  function test(n){ 
      this.a = n+1 ;
    return  [];
  }

  console.log(new test(3))